# -*- coding: utf-8 -*-

import random
import os
import gobject
import gtk
import pygame
import Formation
import Role
import Rule
import Strategy
import Specification
import pango
from pygame.locals import *
from utility import *
from ui import *

__author__="fabien"
__date__ ="$Nov 11, 2010 5:02:41 PM$"

WINX = 1440
WINY = 880

class EntryPoint:
  fps = 30
  playing = False
  realSizeMode = True
  internationalSize = True
  game = None

  def __init__(self, winX, winY):
    window = gtk.Window()
    window.connect('delete-event', gtk.main_quit)
    window.set_title("PySoc")
    window.set_resizable(False)
    vbox = gtk.VBox(False, 1)
    window.add(vbox)

    hbox = gtk.HBox(False, 2)
    hbox.set_border_width(5)
    self.appendAllComponents(hbox)
    vbox.pack_start(hbox, False, False, 0)

    area = gtk.DrawingArea()
    area.set_app_paintable(True)
    area.set_size_request(winX, winY)
    vbox.pack_start(area, False, False, 0)
    area.realize()

    # Force SDL to write on our drawing area
    os.putenv('SDL_WINDOWID', str(area.window.xid))

    # We need to flush the XLib event loop otherwise we can't
    # access the XWindow which set_mode() requires
    gtk.gdk.flush()

    random.seed()
    pygame.init()
    pygame.display.set_mode((winX, winY), 0, 0)
    pygame.mouse.set_visible(True)
    self.screen = pygame.display.get_surface()

    self.field = Field()
    self.setGame()

    gobject.idle_add(pygame.display.update)

    window.show_all()

    clock = pygame.time.Clock()
    while 1:
      # pygame/SDL event processing goes here
      if self.playing:
        self.game.update()
        self.game.draw()
        self.updateLabels()
      pygame.display.flip()
      gtk.main_iteration(False)
      clock.tick(self.fps)

  def appendAllComponents(self, box):
    renderingFrame = gtk.Frame("Rendering")
    box.pack_start(renderingFrame, False, False, 0)
    vbox  = gtk.VBox(True, 4)
    vbox.set_border_width(5)
    renderingFrame.add(vbox)
    
    hbox  = gtk.HBox(False, 3)
    label = gtk.Label("Speed:   ")
    hbox.pack_start(label, False, False, 0)
    adj = gtk.Adjustment(self.fps, 20, 70, 1, 0, 0)
    spinner = gtk.SpinButton(adj, 0, 0)
    spinner.connect("value_changed", self.changeFps, spinner)
    hbox.pack_start(spinner, True, True, 0)
    label = gtk.Label("FPS")
    hbox.pack_start(label, False, False, 0)
    vbox.pack_start(hbox, False, False, 0)

    hbox  = gtk.HBox(False, 3)
    label = gtk.Label("Field length:   ")
    hbox.pack_start(label, False, False, 0)
    adj = gtk.Adjustment(105, 90, 120, 1, 0, 0)
    self.flSpinner = gtk.SpinButton(adj, 0, 0)
    self.flSpinner.connect("value_changed", self.changeFieldLength, self.flSpinner)
    hbox.pack_start(self.flSpinner, True, True, 0)
    label = gtk.Label("meters")
    hbox.pack_start(label, False, False, 0)
    vbox.pack_start(hbox, False, False, 0)

    hbox  = gtk.HBox(False, 3)
    label = gtk.Label("Field width:   ")
    hbox.pack_start(label, False, False, 0)
    adj = gtk.Adjustment(68, 45, 90, 1, 0, 0)
    self.fwSpinner = gtk.SpinButton(adj, 0, 0)
    self.fwSpinner.connect("value_changed", self.changeFieldWidth, self.fwSpinner)
    hbox.pack_start(self.fwSpinner, True, True, 0)
    label = gtk.Label("meters")
    hbox.pack_start(label, False, False, 0)
    vbox.pack_start(hbox, False, False, 0)

    self.internationalSizeCheck = gtk.CheckButton("International size")
    self.internationalSizeCheck.set_active(self.internationalSize)
    self.internationalSizeCheck.connect("toggled", self.internationalSizeToggled, self.internationalSizeCheck)
    vbox.pack_start(self.internationalSizeCheck, False, False, 0)

    check = gtk.CheckButton("Real size for ball and players")
    check.set_active(self.realSizeMode)
    check.connect("toggled", self.realSizeToggled, check)
    vbox.pack_start(check, False, False, 0)

    gameFrame = gtk.Frame("Game")
    box.pack_start(gameFrame, True, True, 0)
    hhbox = gtk.HBox(False, 3)
    hhbox.set_border_width(5)
    gameFrame.add(hhbox)

    vbox = gtk.VBox(False, 5)
    hhbox.pack_start(vbox, False, False, 0)
    self.labelTeam1 = gtk.Label("   Équipe   ")
    self.labelTeam1.modify_font(pango.FontDescription("sans 14"))
    vbox.pack_start(self.labelTeam1, False, False, 0)
    self.scoreTeam1 = gtk.Label("0")
    self.scoreTeam1.modify_font(pango.FontDescription("sans 24"))
    vbox.pack_start(self.scoreTeam1, False, False, 0)
    frame = gtk.Frame("Mode")
    vbox.pack_start(frame, False, False, 0)
    hbox = gtk.HBox(False, 2)
    frame.add(hbox)
    button = gtk.RadioButton(None, "Idiot")
    button.set_active(True)
    button.connect("toggled", self.changeMode, 10)
    hbox.pack_start(button, False, False, 0)
    button.show()
    button = gtk.RadioButton(button, "Advanced")
    button.connect("toggled", self.changeMode, 11)
    hbox.pack_start(button, False, False, 0)
    button.show()
    self.initialFormationTeam1 = gtk.Frame("Initial formation")
    vbox.pack_start(self.initialFormationTeam1, False, False, 0)
    hbox = gtk.HBox(False, 2)
    self.initialFormationTeam1.add(hbox)
    button = gtk.RadioButton(None, "Standard")
    button.set_active(False)
    button.connect("toggled", self.changeInitialFormationTeam1)
    hbox.pack_start(button, False, False, 0)
    self.team1standardFormationButton = button
    button.show()
    button = gtk.RadioButton(button, "Attack")
    button.set_active(True)
    button.connect("toggled", self.changeInitialFormationTeam1)
    hbox.pack_start(button, False, False, 0)
    self.team1attackFormationButton = button
    button.show()
    self.statusTeam1 = gtk.Label("Sleeping")
    vbox.pack_start(self.statusTeam1, False, False, 0)

    vbox = gtk.VBox(True, 2)
    hhbox.pack_start(vbox, True, True, 0)
    self.resetButton = gtk.Button("Reset")
    self.resetButton.set_sensitive(False)
    self.resetButton.connect("clicked", self.stopGame, self.resetButton)
    vbox.pack_start(self.resetButton, False, True, 0)
    self.playPauseButton = gtk.Button("Play")
    self.playPauseButton.connect("clicked", self.playPauseGame, self.playPauseButton)
    vbox.pack_start(self.playPauseButton, False, True, 0)

    vbox = gtk.VBox(False, 5)
    hhbox.pack_start(vbox, False, False, 0)
    self.labelTeam2 = gtk.Label("   Équipe   ")
    self.labelTeam2.modify_font(pango.FontDescription("sans 14"))
    vbox.pack_start(self.labelTeam2, False, False, 0)
    self.scoreTeam2 = gtk.Label("0")
    self.scoreTeam2.modify_font(pango.FontDescription("sans 24"))
    vbox.pack_start(self.scoreTeam2, False, False, 0)
    frame = gtk.Frame("Mode")
    vbox.pack_start(frame, False, False, 0)
    hbox = gtk.HBox(False, 2)
    frame.add(hbox)
    button = gtk.RadioButton(None, "Idiot")
    button.set_active(True)
    button.connect("toggled", self.changeMode, 20)
    hbox.pack_start(button, False, False, 0)
    button.show()
    button = gtk.RadioButton(button, "Advanced")
    button.connect("toggled", self.changeMode, 21)
    hbox.pack_start(button, False, False, 0)
    button.show()
    self.initialFormationTeam2 = gtk.Frame("Initial formation")
    vbox.pack_start(self.initialFormationTeam2, False, False, 0)
    hbox = gtk.HBox(False, 2)
    self.initialFormationTeam2.add(hbox)
    button = gtk.RadioButton(None, "Standard")
    button.set_active(True)
    button.connect("toggled", self.changeInitialFormationTeam2)
    hbox.pack_start(button, False, False, 0)
    self.team2standardFormationButton = button
    button.show()
    button = gtk.RadioButton(button, "Attack")
    button.set_active(False)
    button.connect("toggled", self.changeInitialFormationTeam2)
    hbox.pack_start(button, False, False, 0)
    self.team2attackFormationButton = button
    button.show()
    self.statusTeam2 = gtk.Label("Sleeping")
    vbox.pack_start(self.statusTeam2, False, False, 0)

  def updateLabels(self):
    self.scoreTeam1.set_markup("<span foreground=\"blue\">" + str(self.game.team1.score) + "</span>")
    self.scoreTeam2.set_markup("<span foreground=\"red\">" + str(self.game.team2.score) + "</span>")
    team1Status = "Sleeping"
    team2Status = "Sleeping"
    if not self.game.pause:
      if self.game.team1.isAttacking: team1Status = "Attacking"
      else:                           team1Status = "Defending"
      if self.game.team2.isAttacking: team2Status = "Attacking"
      else:                           team2Status = "Defending"
    self.statusTeam1.set_markup("<span foreground=\"blue\">" + team1Status + "</span>")
    self.statusTeam2.set_markup("<span foreground=\"red\">" + team2Status + "</span>")

  def changeFps(self, widget, spin):
    self.fps = widget.get_value_as_int()

  def changeFieldLength(self, widget, spin):
    self.stop(True)
    l = widget.get_value_as_int()
    self.field.setLength(l)
    self.isInInternationalSize()
    self.field.initZones()
    self.stop(True)

  def changeFieldWidth(self, widget, spin):
    self.stop(True)
    w = widget.get_value_as_int()
    self.field.setWidth(w)
    self.isInInternationalSize()
    self.field.initZones()
    self.stop(True)

  def changeMode(self, wiget, data=None):
    if self.game == None: return
    if data == 10:
      self.game.team1.setStrategy(Strategy.Lame())
      print 'lame'
    if data == 11: self.game.team1.setStrategy(Strategy.Advanced())
    if data == 20: self.game.team2.setStrategy(Strategy.Lame())
    if data == 21: self.game.team2.setStrategy(Strategy.Advanced())

  def changeInitialFormationTeam1(self, widget):
    if self.game == None: return
    std = self.team1standardFormationButton.get_active()
    if std:
      self.game.team1.formation = Formation.Standard(self.field)
      if not self.team2attackFormationButton.get_active():
        self.team2attackFormationButton.set_active(True)
    else:
      self.game.team1.formation = Formation.Attack(self.field)
      if not self.team2standardFormationButton.get_active():
        self.team2standardFormationButton.set_active(True)
    self.game.team1.applyFormation()
    self.game.draw()

  def changeInitialFormationTeam2(self, widget):
    if self.game == None: return
    std = self.team2standardFormationButton.get_active()
    if std:
      self.game.team2.formation = Formation.Standard(self.field, True)
      if not self.team1attackFormationButton.get_active():
        self.team1attackFormationButton.set_active(True)
    else:
      self.game.team2.formation = Formation.Attack(self.field, True)
      if not self.team1standardFormationButton.get_active():
        self.team1standardFormationButton.set_active(True)
    self.game.team2.applyFormation()
    self.game.draw()


  def playPauseGame(self, widget, data):
    if not self.playing:
      self.stop(True)
    self.playing = True
    self.resetButton.set_sensitive(True)
    self.flSpinner.set_sensitive(False)
    self.fwSpinner.set_sensitive(False)
    self.internationalSizeCheck.set_sensitive(False)
    self.initialFormationTeam1.set_sensitive(False)
    self.initialFormationTeam2.set_sensitive(False)
    self.game.pause = not self.game.pause
    if self.game.pause:
      widget.set_label("Play")
    else:
      widget.set_label("Pause")

  def stopGame(self, widget, data): self.stop(True)
  def stop(self, stop):
    self.playing = False
    if stop:
      self.playPauseButton.set_label("Play")
      self.resetButton.set_sensitive(False)
      self.flSpinner.set_sensitive(True)
      self.fwSpinner.set_sensitive(True)
      self.internationalSizeCheck.set_sensitive(True)
      self.initialFormationTeam1.set_sensitive(True)
      self.initialFormationTeam2.set_sensitive(True)
      self.setGame()

  def realSizeToggled(self, widget, data):
    self.realSizeMode = widget.get_active()
    self.game.setRealSize(self.realSizeMode)
    self.game.draw()

  def isInInternationalSize(self):
    self.internationalSize = self.field.rlength == 105 and self.field.rwidth == 68
    self.internationalSizeCheck.set_active(self.internationalSize)

  def internationalSizeToggled(self, widget, data):
    self.internationalSize = widget.get_active()
    if self.internationalSize:
      self.flSpinner.set_value(105)
      self.fwSpinner.set_value(68)

  def setGame(self):
    ball  = Ball(self.field.getCenterLocation())
    teams = self.getTeams()
    self.game = Game(self.field, teams[0], teams[1], ball, self.screen)
    self.labelTeam1.set_markup("<span foreground=\"blue\">   " + str(teams[0].name) + "   </span>")
    self.labelTeam2.set_markup("<span foreground=\"red\">   " + str(teams[1].name) + "   </span>")
    self.scoreTeam1.set_markup("<span foreground=\"blue\">0</span>")
    self.scoreTeam2.set_markup("<span foreground=\"red\">0</span>")
    self.statusTeam1.set_markup("<span foreground=\"blue\">Sleeping</span>")
    self.statusTeam2.set_markup("<span foreground=\"red\">Sleeping</span>")

    rules = Rule.Game()
    rules.append(Rule.Ball())
    rules.append(Rule.Player())
    rules.append(Rule.Throw())
    rules.append(Rule.BallInGoal())
    rules.append(Rule.BallOnTouchLine())
    rules.append(Rule.BallBehindTheGoal())

    self.game.rules = rules
    self.game.setRealSize(self.realSizeMode)
    self.game.draw()

  def getTeams(self):
    t1 = Team("Team 1", Color.Blue)
    t2 = Team("Team 2", Color.Red)
    strategy1 = Strategy.Lame()
    strategy2 = Strategy.Lame()
    r = Role.Helper.AllRoles.keys()
    for i in range(11):
      p1                 = Player(str(i) + " [Team 1]")
      p1.strategy        = strategy1
      p1.orientation     = DirectionHelper.East
      p1.appendSpecification(Specification.Speed(3))
      p1.appendSpecification(Specification.Agility(50))
      
      p2                 = Player(str(i) + " [Team 2]")
      p2.strategy        = strategy2
      p2.orientation     = DirectionHelper.West
      p2.appendSpecification(Specification.Speed(3))
      p2.appendSpecification(Specification.Agility(10))

      t1.addPlayer(p1, Role.Helper.AllRoles[r[i]])
      t2.addPlayer(p2, Role.Helper.AllRoles[r[i]])

    t1.formation = Formation.Attack(self.field)
    t2.formation = Formation.Standard(self.field, True)
    t1.applyFormation()
    t2.applyFormation()

    return (t1, t2)

if __name__ == "__main__":
  EntryPoint(WINX, WINY)